#ifndef LENGTHEDGEATTRIBUTES_H_
#define LENGTHEDGEATTRIBUTES_H_

#include "graph_support/Graph.h"

namespace GRAPH_SUPPORT_NS
{
namespace attributes
{

// TODO: common style of location length attributes and flow attributes
class LengthEdgeAttributes : public Graph::EdgeAttributes
{
public:
	/**
	 * type of edge length
	 */
	class EdgeLength
	{
	public:
		/**
		 * casts double -> length
		 */
		EdgeLength( double );
		const EdgeLength & operator = ( const int & );
		bool operator == ( const EdgeLength & ) const;
		bool operator != ( const EdgeLength & ) const;
		bool operator > ( const EdgeLength & ) const;
		bool operator < ( const EdgeLength & ) const;
		bool operator >= ( const EdgeLength & ) const;
		bool operator <= ( const EdgeLength & ) const;
		EdgeLength operator + ( const EdgeLength & ) const;
		EdgeLength operator - ( const EdgeLength & ) const;
		const EdgeLength & operator += ( const EdgeLength & );
		const EdgeLength & operator -= ( const EdgeLength & );
	};

	/**
	 * returns +infinity value of edge length
	 */
	static EdgeLength getINFLength();
};

class Length1EdgeAttributes : public Graph::EdgeAttributes
{
public:
	typedef int EdgeLength;

	EdgeLength getLength()
	{
		return 1;
	}

	static EdgeLength getINFLength()
	{
		return 1 << 30;
	}

	void onBidirEdgeCreated( Length1EdgeAttributes &, bool isOriginalEdge = true )
	{
	}

	bool operator == ( const Length1EdgeAttributes & that ) const
	{
		return true;
	}
};

/**
 * if another type/value of INF is wanted - it is supposed to
 * implement another EdgeLength
 *
 * T is expected to have:
 * T( int );
 * const T & operator = ( const int & );
 *
 */
// TODO: double inf !!!
template< typename T, long INF = 1 << 30 >
class LengthEdgeAttributesTmpl : public LengthEdgeAttributes
{
public:
	typedef T EdgeLength;

	LengthEdgeAttributesTmpl( T value = 0 )
		: value( value )
	{
	}

	EdgeLength getLength()
	{
		return value;
	}

	void setLength( const EdgeLength & value )
	{
		this->value = value;
	}

	static EdgeLength getINFLength()
	{
		return INF;
	}

	void onBidirEdgeCreated( LengthEdgeAttributesTmpl< T, INF > &, bool isOriginalEdge = true )
	{
	}

private:
	T value;
};

}
}

#endif /* LENGTHEDGEATTRIBUTES_H_ */
